package com.nlscan.ncomgateway.core.sdk.http

import android.text.TextUtils
import android.util.Log
import com.nlscan.ble.util.NLogUtil
import com.nlscan.ncomgateway.core.data.preference.SettingsPreferenceManager
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.security.SecureRandom
import java.security.cert.CertificateException
import java.security.cert.X509Certificate
import java.util.concurrent.TimeUnit
import javax.net.ssl.SSLContext
import javax.net.ssl.SSLSocketFactory
import javax.net.ssl.TrustManager
import javax.net.ssl.X509TrustManager

object RetrofitClient {

    //请求的地址
//    val BASE_URL = "https://wanandroid.com/"

    //retrofit对象
    private var retrofit: Retrofit? = null

    //请求的api，可以根据不同的场景设置多个
//    val service: ApiService by lazy {
//        getRetrofit().create(ApiService::class.java)
//    }
    private var sslSocketFactory: SSLSocketFactory? = null

    private var mHttpOutputApi: HttpOutputApi? = null

    fun getHttpOutputApi(): HttpOutputApi? {
        val ipProtocol = SettingsPreferenceManager.getIpOutputProtocol()
        val isHttpOrHttps = SettingsPreferenceManager.isHttpOrHttpsOutputMode()
        if (!isHttpOrHttps) {
            NLogUtil.e("getHttpOutputApi failed! ipProtocol is not http(s)")
            return null
        }
        val hostname = getCorrectHostname()
        if (TextUtils.isEmpty(hostname)) {
            NLogUtil.e("getHttpOutputApi failed! http(s) hostname is null!!!")
            return null
        }
        if (mHttpOutputApi == null) {
            val baseUrl = "${ipProtocol}://${hostname}/"
            NLogUtil.i("getHttpOutputApi baseUrl: $baseUrl")
            val retrofit = getRetrofit(baseUrl)
            mHttpOutputApi = retrofit?.create(HttpOutputApi::class.java)
        }
        return mHttpOutputApi
    }

    fun resetHttpOutputApi() {
        //fix:修复hostname修改未生效问题
        //原因：retrofit未设置为null，导致仍然使用之前的 retrofit对象
        retrofit = null
        mHttpOutputApi = null
    }


    private fun getCorrectHostname(): String {
        //fix:适配域名栏用户填写带了 https:// 前缀，导致获取到的 baseUrl 为：https://https//www.kelgray.cloud/
        var hostname = SettingsPreferenceManager.getIpOutputHostname()
        hostname = hostname.removePrefix("http://")
        hostname = hostname.removePrefix("https://")
        //fix: https://www.kelgray.cloud/ipsapi/api/v1.0/Scans/add? 避免报错，这种写法也不支持，只是避免报错
        hostname = hostname.removeSuffix("?")
        //fix: 域名带 /
        hostname = hostname.removeSuffix("/")
        return hostname
    }


    private fun getRetrofit(url: String): Retrofit? {
        if (retrofit == null) {
            NLogUtil.i("getRetrofit create retrofit url: $url")
            try {
                retrofit = Retrofit.Builder()
                    //fix: 客户在域名输入 https://www.kelgray.cloud/ipsapi/api/v1.0/Scans/add? 导致报错
                    //Error: java.lang.IllegalArgumentException: baseUrl must end in /: https://www.kelgray.cloud/api/ass?/
                    .baseUrl(url)
                    .client(getOkHttpClient())
                    .addConverterFactory(GsonConverterFactory.create())
//                .addCallAdapterFactory(CoroutineCallAdapterFactory())
                    .build()
            } catch (e: Exception) {
                NLogUtil.e(e.message)
            }
        }
        return retrofit
    }

    /**
     * 获取 OkHttpClient
     */
    private fun getOkHttpClient(): OkHttpClient {
        val builder = OkHttpClient().newBuilder()
        val loggingInterceptor: HttpLoggingInterceptor
//        if (BuildConfig.DEBUG) {
//            httpLoggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
//        } else {
//            httpLoggingInterceptor.level = HttpLoggingInterceptor.Level.NONE
//        }

//        if (BuildConfig.DEBUG) {
        loggingInterceptor =
                HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger {
                    override fun log(message: String) {
                        Log.d("接口请求log----->", message)
                    }
                })
        loggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
//        } else loggingInterceptor = HttpLoggingInterceptor()

        //设置 请求的缓存的大小跟位置
        //todo method 'java.io.File android.content.Context.getCacheDir()' on a null object reference
//        val cacheFile = File(mContext.cacheDir, "cache")
//        val cache = Cache(cacheFile, HttpConstant.MAX_CACHE_SIZE)


//            TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
//                    TrustManagerFactory.getDefaultAlgorithm());
//            trustManagerFactory.init((KeyStore) null);
//            TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
        val trustManager: X509TrustManager = object : X509TrustManager {
            @Throws(CertificateException::class)
            override fun checkClientTrusted(chain: Array<X509Certificate>, authType: String) {
            }

            @Throws(CertificateException::class)
            override fun checkServerTrusted(chain: Array<X509Certificate>, authType: String) {
            }

            override fun getAcceptedIssuers(): Array<X509Certificate> {
                return arrayOf()
            }
        }

        builder.run {
            addInterceptor(loggingInterceptor)
//            addInterceptor(HeaderInterceptor())
//            addInterceptor(SaveCookieInterceptor())
//            addInterceptor(CacheInterceptor())
//            cache(cache)  //添加缓存
            connectTimeout(HttpConstant.DEFAULT_TIMEOUT, TimeUnit.SECONDS)
            readTimeout(HttpConstant.DEFAULT_TIMEOUT, TimeUnit.SECONDS)
            writeTimeout(HttpConstant.DEFAULT_TIMEOUT, TimeUnit.SECONDS)
            retryOnConnectionFailure(true) // 错误重连
            // cookieJar(CookieManager())
            sslSocketFactory(getSSLSocketFactory(),trustManager)
            hostnameVerifier(org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER)
        }
        return builder.build()
    }


//    private fun SSLSocketFactory getSSLSocketFactory() {
//        val trustAllCerts = TrustManager
//    }

    /**
     * 自定义SSLSocket, 忽略验证客户端和服务端证书。
     * @return
     * @throws Exception
     */
    private fun getSSLSocketFactory(): SSLSocketFactory {
        if (sslSocketFactory == null) {
            try {
                val sslContext = SSLContext.getInstance("SSL")
                sslContext.init(null, getTrustManager(), SecureRandom())
                sslSocketFactory = sslContext.socketFactory
            } catch (e: Exception) {
                throw RuntimeException(e)
            }
        }
        return sslSocketFactory!!
    }

    private fun getTrustManager(): Array<TrustManager>? {
        return arrayOf(
            object : X509TrustManager {
                override fun checkServerTrusted(chain: Array<X509Certificate>, authType: String) {}

                @Throws(CertificateException::class)
                override fun checkClientTrusted(
                    x509Certificates: Array<X509Certificate>,
                    s: String
                ) {
                }

                override fun getAcceptedIssuers(): Array<X509Certificate> {
                    return arrayOf()
                }
            }
        )
    }

}